package com.tian.core.token;

import cn.hutool.core.util.StrUtil;
import com.tian.core.beans.ResultBean;
import com.tian.core.lang.Constant;
import com.tian.core.lang.ErrorDefine;
import io.jsonwebtoken.*;
import org.springframework.stereotype.Component;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;
import java.util.Map;

/**
 * 生成 token
 */
@Component
public class TokenManage {
    /**
     * 秘钥
     */
//    @Value("${jwt.secretKey}")
    private String secretKey;
    /**
     * 过期时间
     */
//    @Value("${jwt.expirationMillis}")
    private Long expirationMillis;

    /**
     * 生成token
     */
    public String createJwt(Map<String, Object> payload, String subject) {
        Long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        Key key = generalKey();
        JwtBuilder builder = Jwts.builder()
                .setClaims(payload)
                // 签发时间
                .setIssuedAt(now)
                // 签发者
                .setIssuer(Constant.JWT_ISSUSER)
                // 该JWT所面向的用户
                .setSubject(subject)
                // 过期时间
                .setExpiration(now)
                // 再次加密
                .signWith(SignatureAlgorithm.HS256, key);
        if (expirationMillis > 0) {
            builder.setExpiration(new Date(nowMillis + expirationMillis));
        }
        return builder.compact();
    }

    /**
     * 加密
     *
     * @return
     */
    private Key generalKey() {
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(secretKey);
        return new SecretKeySpec(apiKeySecretBytes, "AES");
    }

    /**
     * 校验 token
     *
     * @param token
     * @param resultBean
     * @return
     */
    public Object verify(String token, ResultBean<?> resultBean) {
        // 如果token为空直接返回错误信息
        if (StrUtil.isBlank(token)) {
            resultBean.setRespCode(ErrorDefine.TOKEN_ERROR);
            resultBean.setRespMsg(ErrorDefine.TOKEN_ERROR_MSG);
            return resultBean;
        }
        try {
            Jwts.parser()
                    .setSigningKey(generalKey())
                    .parseClaimsJws(token).getBody();
        } catch (ExpiredJwtException expiredJwtException) {
            //token超时
            resultBean.setRespCode(ErrorDefine.TOKEN_TIMEOUT);
            resultBean.setRespMsg(ErrorDefine.TOKEN_TIMEOUT_MSG);
        } catch (MalformedJwtException malformedJwtException) {
            //token验证失败
            resultBean.setRespCode(ErrorDefine.TOKEN_ERROR);
            resultBean.setRespMsg(ErrorDefine.TOKEN_ERROR_MSG);
        }
        return resultBean;
    }

    public String getSecretKey() {
        return secretKey;
    }

    public void setSecretKey(String secretKey) {
        this.secretKey = secretKey;
    }

    public Long getExpirationMillis() {
        return expirationMillis;
    }

    public void setExpirationMillis(Long expirationMillis) {
        this.expirationMillis = expirationMillis;
    }
}
